package me.keiwu.pub.util;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Created by kei on 13/11/2017.
 */
public class EntityUtil {


    private static final Logger logger = LoggerFactory.getLogger(EntityUtil.class);


    /**
     * 复制对象
     * @param src
     * @param target
     * @param <T>
     * @return
     */
    public static <T> T copyProperties(Object src, T target) {
        BeanUtils.copyProperties(src, target);
        return target;
    }


    /**
     * 复制对象，忽略null值字段
     * @param src 源对象
     * @param target 目标对象
     * @param <T>
     * @return
     */
    public static <T> T copyNonNullProperties(Object src, T target) {
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
        return target;
    }

    /**
     * 复制对象，忽略null值或者空字符串字段
     * @param src 源对象
     * @param target 目标对象
     * @param <T>
     * @return
     */
    public static  <T> T copyNonBlankProperties(Object src, T target) {
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src, true));
        return target;
    }



    public static String[] getNullPropertyNames (Object source) {
        return getNullPropertyNames(source, false);
    }

    public static String[] getNullPropertyNames (Object source, boolean ignoreBlank) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<>();
        for(PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (ignoreBlank && srcValue instanceof String && StringUtils.isBlank((String) srcValue)) {
                emptyNames.add(pd.getName());
            } else if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }



    public static Map<String, Object> transBean2Map(Object obj) {
        if(obj == null) return null;
        try {
            Map<String, Object> map = new HashMap<>();
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                // 过滤class属性
                if (!key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);
                    map.put(key, value);
                }
            }
            return map;
        } catch (Exception e) {
            logger.error("transBean2Map exception: ", e);
            return null;
        }

    }

}
